package com.sgu6.sgu6_machine.service;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;

import com.sgu6.middleware.util.HexUtil;
import com.sgu6.serialport.api.SerialPortFinder;
import com.sgu6.serialport.dto.DeviceDto;
import com.sgu6.serialport.manager.SerialPortManagerForCard;
import com.sgu6.serialport.utils.CheckTool;
import com.sgu6.sgu6_machine.config.MachineConfig;
import com.sgu6.sgu6_machine.container.MachineContainer;
import com.sgu6.sgu6_machine.event.CardComEvent;
import com.sgu6.sgu6_machine.event.ReadCardEvent;
import com.sgu6.sgu6_machine.util.ToastUtil;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.io.File;
import java.util.ArrayList;

/**
 * 后台服务,接收和发送串口指令
 * <p>
 * back service
 * receive and sent serial port command from single machine
 */
public class ReadCardS extends Service implements SerialPortManagerForCard.OnSerialPortOpenListener, SerialPortManagerForCard.OnSerialPortIOListener {

    private final String TAG = ReadCardS.class.getCanonicalName();

    private MachineConfig machineConfig = new MachineConfig();

    private String cmd = "";//储存完整的指令，串口没有一次将完整的指令全部发过来因此要分段接收

    public ReadCardS() {
    }

    @Override
    public void onSucceed(File device) {
        Log.v(TAG, "serial port open onSucceed: ");
    }

    @Override
    public void onFailure(File device, Status status) {
        Log.v(TAG, "serial port open onFailure: ");
    }

    @Override
    public void onDataReceived(byte[] bytes) {
        Log.v(TAG, "onDataReceived: " + HexUtil.Bytes2HexString(bytes));
        String b = HexUtil.Bytes2HexString(bytes);
        cmd = cmd + b;
        while (true) {
            String c = CheckTool.checkCmdForCard(cmd);
            if (c != null) {
                EventBus.getDefault().post(new ReadCardEvent(c));
                cmd = "";
            } else {
                break;
            }
        }
    }

    @Override
    public void onDataSent(byte[] bytes) {
        Log.v(TAG, "onDataSent: " + HexUtil.Bytes2HexString(bytes));
        EventBus.getDefault().post(new ReadCardEvent(HexUtil.Bytes2HexString(bytes)));
    }

    public class MachineBinder extends Binder {
        public ReadCardS getService() {
            return ReadCardS.this;
        }
    }

    private final MachineBinder binder = new MachineBinder();

    @Override
    public void onCreate() {
        super.onCreate();
        if (!EventBus.getDefault().isRegistered(this)) {
            EventBus.getDefault().register(this);
        }
        initSerialPort();
    }


    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return START_NOT_STICKY;
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        return binder;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        EventBus.getDefault().unregister(this);
        SerialPortManagerForCard.getInstance().closeSerialPort();
    }

    /**
     * 初始化串口
     * serial port init
     */
    private void initSerialPort() {
        SerialPortFinder serialPortFinder = new SerialPortFinder();
        ArrayList<DeviceDto> devices = serialPortFinder.getDevices();
        for (int i = 0; i < devices.size(); i++) {
            if (devices.get(i).getFile().getAbsolutePath().equals(MachineContainer.machineConfigDto.cardComPath)) {
//            if (devices.get(i).getFile().getAbsolutePath().equals("/dev/ttyS4")) {
                boolean isOpen = SerialPortManagerForCard.getInstance().setOnSerialPortIOListener(this).setOnOpenSerialPortListener(this).openSerialPort(devices.get(i).getFile(), MachineContainer.machineConfigDto.baudrate);
                if (isOpen) {
                    Log.i(TAG, "串口打开成功");
                } else {
                    Log.i(TAG, "串口打开失败");
                }
            }
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onComEvent(CardComEvent event) {
        MachineContainer.machineConfigDto.cardComPath = event.device.getFile().getAbsolutePath();
        try {
            machineConfig.updateMachineConfig(this);
        } catch (Exception e) {
        }
        SerialPortManagerForCard.getInstance().closeSerialPort();
        boolean isOpen = SerialPortManagerForCard.getInstance().setOnSerialPortIOListener(this).setOnOpenSerialPortListener(this).openSerialPort(event.device.getFile(), MachineContainer.machineConfigDto.baudrate);
        ToastUtil.show(this, "串口[" + event.device.getName() + "]打开" + (isOpen ? "成功" : "失败"));
    }

}
